/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/publicdomain/zero/1.0/
 */
package com.nulldev.util.internal.backport.concurrency9.concurrent;

import java.util.concurrent.CompletionException;
import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * A stage of a possibly asynchronous computation, that performs an action or
 * computes a value when another CompletionStage completes. A stage completes
 * upon termination of its computation, but this may in turn trigger other
 * dependent stages. The functionality defined in this interface takes only a
 * few basic forms, which expand out to a larger set of methods to capture a
 * range of usage styles:
 *
 * <ul>
 *
 * <li>The computation performed by a stage may be expressed as a Function,
 * Consumer, or Runnable (using methods with names including <em>apply</em>,
 * <em>accept</em>, or <em>run</em>, respectively) depending on whether it
 * requires arguments and/or produces results. For example:
 * 
 * <pre> {@code
 * stage.thenApply(x -> square(x)).thenAccept(x -> System.out.print(x)).thenRun(() -> System.out.println());
 * }</pre>
 *
 * An additional form (<em>compose</em>) allows the construction of computation
 * pipelines from functions returning completion stages.
 *
 * <p>
 * Any argument to a stage's computation is the outcome of a triggering stage's
 * computation.
 *
 * <li>One stage's execution may be triggered by completion of a single stage,
 * or both of two stages, or either of two stages. Dependencies on a single
 * stage are arranged using methods with prefix <em>then</em>. Those triggered
 * by completion of <em>both</em> of two stages may <em>combine</em> their
 * results or effects, using correspondingly named methods. Those triggered by
 * <em>either</em> of two stages make no guarantees about which of the results
 * or effects are used for the dependent stage's computation.
 *
 * <li>Dependencies among stages control the triggering of computations, but do
 * not otherwise guarantee any particular ordering. Additionally, execution of a
 * new stage's computations may be arranged in any of three ways: default
 * execution, default asynchronous execution (using methods with suffix
 * <em>async</em> that employ the stage's default asynchronous execution
 * facility), or custom (via a supplied {@link Executor}). The execution
 * properties of default and async modes are specified by CompletionStage
 * implementations, not this interface. Methods with explicit Executor arguments
 * may have arbitrary execution properties, and might not even support
 * concurrent execution, but are arranged for processing in a way that
 * accommodates asynchrony.
 *
 * <li>Two method forms ({@link #handle handle} and {@link #whenComplete
 * whenComplete}) support unconditional computation whether the triggering stage
 * completed normally or exceptionally. Method {@link #exceptionally
 * exceptionally} supports computation only when the triggering stage completes
 * exceptionally, computing a replacement result, similarly to the java
 * {@code catch} keyword. In all other cases, if a stage's computation
 * terminates abruptly with an (unchecked) exception or error, then all
 * dependent stages requiring its completion complete exceptionally as well,
 * with a {@link CompletionException} holding the exception as its cause. If a
 * stage is dependent on <em>both</em> of two stages, and both complete
 * exceptionally, then the CompletionException may correspond to either one of
 * these exceptions. If a stage is dependent on <em>either</em> of two others,
 * and only one of them completes exceptionally, no guarantees are made about
 * whether the dependent stage completes normally or exceptionally. In the case
 * of method {@code whenComplete}, when the supplied action itself encounters an
 * exception, then the stage completes exceptionally with this exception unless
 * the source stage also completed exceptionally, in which case the exceptional
 * completion from the source stage is given preference and propagated to the
 * dependent stage.
 *
 * </ul>
 *
 * <p>
 * All methods adhere to the above triggering, execution, and exceptional
 * completion specifications (which are not repeated in individual method
 * specifications). Additionally, while arguments used to pass a completion
 * result (that is, for parameters of type {@code T}) for methods accepting them
 * may be null, passing a null value for any other parameter will result in a
 * {@link NullPointerException} being thrown.
 *
 * <p>
 * Method form {@link #handle handle} is the most general way of creating a
 * continuation stage, unconditionally performing a computation that is given
 * both the result and exception (if any) of the triggering CompletionStage, and
 * computing an arbitrary result. Method {@link #whenComplete whenComplete} is
 * similar, but preserves the result of the triggering stage instead of
 * computing a new one. Because a stage's normal result may be {@code null},
 * both methods should have a computation structured thus:
 *
 * <pre>{@code
 * (result, exception) -> {
 * 	if (exception == null) {
 * 		// triggering stage completed normally
 * 	} else {
 * 		// triggering stage completed exceptionally
 * 	}
 * }
 * }</pre>
 *
 * <p>
 * This interface does not define methods for initially creating, forcibly
 * completing normally or exceptionally, probing completion status or results,
 * or awaiting completion of a stage. Implementations of CompletionStage may
 * provide means of achieving such effects, as appropriate. Method
 * {@link #toCompletableFuture} enables interoperability among different
 * implementations of this interface by providing a common conversion type.
 *
 * @author Doug Lea
 * @since 1.8
 */
public interface CompletionStage<T> {
// CVS rev. 1.39
	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed with this stage's result as the argument to the supplied function.
	 *
	 * <p>
	 * This method is analogous to {@link java.util.Optional#map Optional.map} and
	 * {@link java.util.stream.Stream#map Stream.map}.
	 *
	 * <p>
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn  the function to use to compute the value of the returned
	 *            CompletionStage
	 * @param <U> the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenApply(Function<? super T, ? extends U> fn);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed using this stage's default asynchronous execution facility, with
	 * this stage's result as the argument to the supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn  the function to use to compute the value of the returned
	 *            CompletionStage
	 * @param <U> the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenApplyAsync(Function<? super T, ? extends U> fn);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed using the supplied Executor, with this stage's result as the
	 * argument to the supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn       the function to use to compute the value of the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenApplyAsync(Function<? super T, ? extends U> fn, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed with this stage's result as the argument to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenAccept(Consumer<? super T> action);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed using this stage's default asynchronous execution facility, with
	 * this stage's result as the argument to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally, is
	 * executed using the supplied Executor, with this stage's result as the
	 * argument to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally,
	 * executes the given action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenRun(Runnable action);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally,
	 * executes the given action using this stage's default asynchronous execution
	 * facility.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenRunAsync(Runnable action);

	/**
	 * Returns a new CompletionStage that, when this stage completes normally,
	 * executes the given action using the supplied Executor.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed with the two results as arguments to the
	 * supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other the other CompletionStage
	 * @param fn    the function to use to compute the value of the returned
	 *              CompletionStage
	 * @param <U>   the type of the other CompletionStage's result
	 * @param <V>   the function's return type
	 * @return the new CompletionStage
	 */
	public <U, V> CompletionStage<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed using this stage's default asynchronous
	 * execution facility, with the two results as arguments to the supplied
	 * function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other the other CompletionStage
	 * @param fn    the function to use to compute the value of the returned
	 *              CompletionStage
	 * @param <U>   the type of the other CompletionStage's result
	 * @param <V>   the function's return type
	 * @return the new CompletionStage
	 */
	public <U, V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed using the supplied executor, with the two
	 * results as arguments to the supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param fn       the function to use to compute the value of the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the type of the other CompletionStage's result
	 * @param <V>      the function's return type
	 * @return the new CompletionStage
	 */
	public <U, V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T, ? super U, ? extends V> fn, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed with the two results as arguments to the
	 * supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @param <U>    the type of the other CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed using this stage's default asynchronous
	 * execution facility, with the two results as arguments to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @param <U>    the type of the other CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, is executed using the supplied executor, with the two
	 * results as arguments to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the type of the other CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, executes the given action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, executes the given action using this stage's default
	 * asynchronous execution facility.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);

	/**
	 * Returns a new CompletionStage that, when this and the other given stage both
	 * complete normally, executes the given action using the supplied executor.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed with the corresponding result as argument to
	 * the supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other the other CompletionStage
	 * @param fn    the function to use to compute the value of the returned
	 *              CompletionStage
	 * @param <U>   the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed using this stage's default asynchronous
	 * execution facility, with the corresponding result as argument to the supplied
	 * function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other the other CompletionStage
	 * @param fn    the function to use to compute the value of the returned
	 *              CompletionStage
	 * @param <U>   the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed using the supplied executor, with the
	 * corresponding result as argument to the supplied function.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param fn       the function to use to compute the value of the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn, Executor executor);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed with the corresponding result as argument to
	 * the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed using this stage's default asynchronous
	 * execution facility, with the corresponding result as argument to the supplied
	 * action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, is executed using the supplied executor, with the
	 * corresponding result as argument to the supplied action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, executes the given action.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, executes the given action using this stage's default
	 * asynchronous execution facility.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other  the other CompletionStage
	 * @param action the action to perform before completing the returned
	 *               CompletionStage
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action);

	/**
	 * Returns a new CompletionStage that, when either this or the other given stage
	 * complete normally, executes the given action using the supplied executor.
	 *
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param other    the other CompletionStage
	 * @param action   the action to perform before completing the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);

	/**
	 * Returns a new CompletionStage that is completed with the same value as the
	 * CompletionStage returned by the given function.
	 *
	 * <p>
	 * When this stage completes normally, the given function is invoked with this
	 * stage's result as the argument, returning another CompletionStage. When that
	 * stage completes normally, the CompletionStage returned by this method is
	 * completed with the same value.
	 *
	 * <p>
	 * To ensure progress, the supplied function must arrange eventual completion of
	 * its result.
	 *
	 * <p>
	 * This method is analogous to {@link java.util.Optional#flatMap
	 * Optional.flatMap} and {@link java.util.stream.Stream#flatMap Stream.flatMap}.
	 *
	 * <p>
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn  the function to use to compute another CompletionStage
	 * @param <U> the type of the returned CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);

	/**
	 * Returns a new CompletionStage that is completed with the same value as the
	 * CompletionStage returned by the given function, executed using this stage's
	 * default asynchronous execution facility.
	 *
	 * <p>
	 * When this stage completes normally, the given function is invoked with this
	 * stage's result as the argument, returning another CompletionStage. When that
	 * stage completes normally, the CompletionStage returned by this method is
	 * completed with the same value.
	 *
	 * <p>
	 * To ensure progress, the supplied function must arrange eventual completion of
	 * its result.
	 *
	 * <p>
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn  the function to use to compute another CompletionStage
	 * @param <U> the type of the returned CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);

	/**
	 * Returns a new CompletionStage that is completed with the same value as the
	 * CompletionStage returned by the given function, executed using the supplied
	 * Executor.
	 *
	 * <p>
	 * When this stage completes normally, the given function is invoked with this
	 * stage's result as the argument, returning another CompletionStage. When that
	 * stage completes normally, the CompletionStage returned by this method is
	 * completed with the same value.
	 *
	 * <p>
	 * To ensure progress, the supplied function must arrange eventual completion of
	 * its result.
	 *
	 * <p>
	 * See the {@link CompletionStage} documentation for rules covering exceptional
	 * completion.
	 *
	 * @param fn       the function to use to compute another CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the type of the returned CompletionStage's result
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this stage completes either normally
	 * or exceptionally, is executed with this stage's result and exception as
	 * arguments to the supplied function.
	 *
	 * <p>
	 * When this stage is complete, the given function is invoked with the result
	 * (or {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments, and the function's result is used to complete the
	 * returned stage.
	 *
	 * @param fn  the function to use to compute the value of the returned
	 *            CompletionStage
	 * @param <U> the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);

	/**
	 * Returns a new CompletionStage that, when this stage completes either normally
	 * or exceptionally, is executed using this stage's default asynchronous
	 * execution facility, with this stage's result and exception as arguments to
	 * the supplied function.
	 *
	 * <p>
	 * When this stage is complete, the given function is invoked with the result
	 * (or {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments, and the function's result is used to complete the
	 * returned stage.
	 *
	 * @param fn  the function to use to compute the value of the returned
	 *            CompletionStage
	 * @param <U> the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);

	/**
	 * Returns a new CompletionStage that, when this stage completes either normally
	 * or exceptionally, is executed using the supplied executor, with this stage's
	 * result and exception as arguments to the supplied function.
	 *
	 * <p>
	 * When this stage is complete, the given function is invoked with the result
	 * (or {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments, and the function's result is used to complete the
	 * returned stage.
	 *
	 * @param fn       the function to use to compute the value of the returned
	 *                 CompletionStage
	 * @param executor the executor to use for asynchronous execution
	 * @param <U>      the function's return type
	 * @return the new CompletionStage
	 */
	public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);

	/**
	 * Returns a new CompletionStage with the same result or exception as this
	 * stage, that executes the given action when this stage completes.
	 *
	 * <p>
	 * When this stage is complete, the given action is invoked with the result (or
	 * {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments. The returned stage is completed when the action returns.
	 *
	 * <p>
	 * Unlike method {@link #handle handle}, this method is not designed to
	 * translate completion outcomes, so the supplied action should not throw an
	 * exception. However, if it does, the following rules apply: if this stage
	 * completed normally but the supplied action throws an exception, then the
	 * returned stage completes exceptionally with the supplied action's exception.
	 * Or, if this stage completed exceptionally and the supplied action throws an
	 * exception, then the returned stage completes exceptionally with this stage's
	 * exception.
	 *
	 * @param action the action to perform
	 * @return the new CompletionStage
	 */
	public CompletionStage<T> whenComplete(BiConsumer<? super T, ? super Throwable> action);

	/**
	 * Returns a new CompletionStage with the same result or exception as this
	 * stage, that executes the given action using this stage's default asynchronous
	 * execution facility when this stage completes.
	 *
	 * <p>
	 * When this stage is complete, the given action is invoked with the result (or
	 * {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments. The returned stage is completed when the action returns.
	 *
	 * <p>
	 * Unlike method {@link #handleAsync(BiFunction) handleAsync}, this method is
	 * not designed to translate completion outcomes, so the supplied action should
	 * not throw an exception. However, if it does, the following rules apply: If
	 * this stage completed normally but the supplied action throws an exception,
	 * then the returned stage completes exceptionally with the supplied action's
	 * exception. Or, if this stage completed exceptionally and the supplied action
	 * throws an exception, then the returned stage completes exceptionally with
	 * this stage's exception.
	 *
	 * @param action the action to perform
	 * @return the new CompletionStage
	 */
	public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);

	/**
	 * Returns a new CompletionStage with the same result or exception as this
	 * stage, that executes the given action using the supplied Executor when this
	 * stage completes.
	 *
	 * <p>
	 * When this stage is complete, the given action is invoked with the result (or
	 * {@code null} if none) and the exception (or {@code null} if none) of this
	 * stage as arguments. The returned stage is completed when the action returns.
	 *
	 * <p>
	 * Unlike method {@link #handleAsync(BiFunction,Executor) handleAsync}, this
	 * method is not designed to translate completion outcomes, so the supplied
	 * action should not throw an exception. However, if it does, the following
	 * rules apply: If this stage completed normally but the supplied action throws
	 * an exception, then the returned stage completes exceptionally with the
	 * supplied action's exception. Or, if this stage completed exceptionally and
	 * the supplied action throws an exception, then the returned stage completes
	 * exceptionally with this stage's exception.
	 *
	 * @param action   the action to perform
	 * @param executor the executor to use for asynchronous execution
	 * @return the new CompletionStage
	 */
	public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor);

	/**
	 * Returns a new CompletionStage that, when this stage completes exceptionally,
	 * is executed with this stage's exception as the argument to the supplied
	 * function. Otherwise, if this stage completes normally, then the returned
	 * stage also completes normally with the same value.
	 *
	 * @param fn the function to use to compute the value of the returned
	 *           CompletionStage if this CompletionStage completed exceptionally
	 * @return the new CompletionStage
	 */
	public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);

	/**
	 * Returns a {@link CompletableFuture} maintaining the same completion
	 * properties as this stage. If this stage is already a CompletableFuture, this
	 * method may return this stage itself. Otherwise, invocation of this method may
	 * be equivalent in effect to {@code thenApply(x -> x)}, but returning an
	 * instance of type {@code CompletableFuture}.
	 *
	 * @return the CompletableFuture
	 */
	public CompletableFuture<T> toCompletableFuture();
}
